package com.osi.mes.print;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;

import com.datasweep.compatibility.client.ATDefinition;
import com.datasweep.compatibility.client.ATRow;
import com.datasweep.compatibility.client.ATRowFilter;
import com.datasweep.compatibility.client.DatasweepException;
import com.datasweep.compatibility.client.DsList;
import com.datasweep.compatibility.client.Part;
import com.datasweep.compatibility.client.Response;
import com.datasweep.compatibility.pnuts.Functions;
import com.datasweep.compatibility.ui.Time;
import com.datasweep.core.eventlog.EventLog;
import com.osi.mes.base.BaseService;
import com.osi.mes.constants.IDateFormatConstants;
import com.osi.mes.constants.ISystemDataConstants;
import com.osi.mes.print.object.BarCodeRule;
import com.osi.mes.utils.DateTimeUtils;
import com.osi.mes.utils.StringUtils;
import com.rockwell.ftpc.framework.common.XMLUtils;
import com.rockwell.ftpc.framework.common.XmlData;
import com.rockwell.ftpc.framework.exception.MESException;
import com.rockwell.mes.rtmis.middle.utils.MDUtils;

import pnuts.lang.Context;

/**
 * 打印组件
 * @author Nemo
 *
 */
public class PrintComponent extends BaseService implements IPrintConstants{
	
	String labelMatrixPath = null;
	HashMap<Long,String> barcodeTemplate = new HashMap<Long,String>();
	
	private static final String NULL = "";
	
	public PrintComponent(Functions functions) throws MESException
	{
		super(functions);
		initLabelMatrixPath();
	}
	
	private void initLabelMatrixPath() throws MESException
	{
		DsList dsList = getFunctions().getList("LabelMatrixPath");
		if(dsList != null)
		{
			List items = dsList.getItems();
			labelMatrixPath = items.get(0).toString();
		}
		else
		{
			throw new MESException("初始化LabelMatrix路径出错", "打印模块", "打印服务");
		}
		
		DsList dsListTemplate = getFunctions().getList("BarcodeTemplate");
		if(dsListTemplate != null)
		{
			List items = dsListTemplate.getItems();
			for (int i = 0; i < items.size(); i++)
			{
				String str = items.get(i).toString();
				String[] value = str.split("\\,");
				barcodeTemplate.put(Long.valueOf(value[0]), value[1]);
			}
		}
		else
		{
			throw new MESException("初始化模板路径出错", "打印模块", "打印服务");
		}
	}

	public PrintComponent(Context context) throws MESException
	{
		super(context);
		initLabelMatrixPath();
	}


	/**
	 * 获得物料条码
	 */
	public BarCodeRule generateMaterialBarcode() throws Exception
	{
		return generateBarcode(BARCODE_TYPE_MATERIAL);
	}
	
	/**
	 * 获得采样条码
	 */
	public BarCodeRule generateSampleBarcode() throws Exception
	{
		return generateBarcode(BARCODE_TYPE_SAMPLE);
	}
	
	/**
	 * 获得成品条码
	 */
	public BarCodeRule generateBoxBarcode() throws Exception
	{
		return generateBarcode(BARCODE_TYPE_LOT);
	}
	
	/**
	 * 从WMS获得条码
	 */
	public String getBarcodeFromWMS(Part part,String supplier,String supplierNo,String orderNumber,String productionLineName,String printLot,String productQty,int type) throws Exception
	{
		if(isDebug)
		{
			String testBarcode = generateTestBarcode("WMS");
			if(testBarcode != null)
				return testBarcode;
		}
		
		String partDescription = part.getDescription();
		String partNumber = part.getPartNumber();
		
		Hashtable<String, ArrayList<Object>> itemData = new Hashtable<String, ArrayList<Object>>();
		Hashtable<String, ArrayList<Object>> sendData = new Hashtable<String, ArrayList<Object>>();
		Hashtable<String, ArrayList<Object>> wmdsData = new Hashtable<String, ArrayList<Object>>();
		wmdsData.put(
			ISystemDataConstants.WMDS_OPERATOR, toTransferValue(NULL));
		wmdsData.put(
			ISystemDataConstants.WMDS_OPERATE, toTransferValue("CreateLabel"));

		Hashtable<String, ArrayList<Object>> wmdsItem = new Hashtable<String, ArrayList<Object>>();
		wmdsItem.put(
			ISystemDataConstants.WMDS_WMDSITEM_KEY, toTransferValue(NULL));
		wmdsItem.put(
			ISystemDataConstants.WMDS_WMDSITEM_VALUE, toTransferValue(NULL));
		wmdsItem.put(
			ISystemDataConstants.WMDS_WMDSITEM_ITEM_TYPE, toTransferValue(NULL));
		wmdsItem.put(
			ISystemDataConstants.WMDS_WMDSITEM_REF1, toTransferValue(partDescription));
		String dateTime = DateTimeUtils.formatDate(
			getFunctions().getDBTime(), IDateFormatConstants.DATE_TIME_FORMAT_DAY);
		wmdsItem.put(
			ISystemDataConstants.WMDS_WMDSITEM_REF2, toTransferValue(dateTime));
		wmdsItem.put(ISystemDataConstants.WMDS_WMDSITEM_REF3,
			toTransferValue(getFunctions().getCurrentUser().getName()));
		wmdsItem.put(
			ISystemDataConstants.WMDS_WMDSITEM_REF4, toTransferValue(supplier==null?NULL:supplier));
		wmdsItem.put(
			ISystemDataConstants.WMDS_WMDSITEM_REF5, toTransferValue(printLot==null?NULL:printLot));
		wmdsItem.put(
			ISystemDataConstants.WMDS_WMDSITEM_REF6, toTransferValue(productQty == null?NULL:productQty));
		wmdsItem.put(
			ISystemDataConstants.WMDS_WMDSITEM_REF7, toTransferValue(partNumber));
		wmdsItem.put(
			ISystemDataConstants.WMDS_WMDSITEM_REF8, toTransferValue(supplierNo==null?NULL:supplierNo));
		wmdsItem.put(
			ISystemDataConstants.WMDS_WMDSITEM_REF9, toTransferValue(dateTime));
		wmdsItem.put(
			ISystemDataConstants.WMDS_WMDSITEM_REF10,toTransferValue(orderNumber==null?NULL:orderNumber));
		wmdsItem.put(
			ISystemDataConstants.WMDS_WMDSITEM_REF11,toTransferValue(productionLineName==null?NULL:productionLineName));
		wmdsItem.put(
			ISystemDataConstants.WMDS_WMDSITEM_REF16,toTransferValue(type));
		wmdsItem.put(
			ISystemDataConstants.WMDS_WMDSITEM_DESCRIPTION, toTransferValue(NULL));
		
		itemData.put(ISystemDataConstants.WMDS_WMDSITEM, toTransferValue(wmdsItem));
		
		wmdsData.put(
			ISystemDataConstants.WMDS_ITEMS, toTransferValue(itemData));
		
		sendData.put(
			ISystemDataConstants.WMDS, toTransferValue(wmdsData));

		String xmlStr = XMLUtils.toXMLStr(sendData);
		
		xmlStr = xmlStr.replaceAll("<xml>", "");
		xmlStr = xmlStr.replaceAll("</xml>", "");
		System.out.println(xmlStr);
		String result = MDUtils.invokeDNetWebService(
			END_POINT, NAME_SPACE, METHOD_NAME_WMDS, SOAP_ACTION_WMDS, PARAMETER_NAME, xmlStr);
		XmlData xmlData = XMLUtils.strToXMLData(result);
		Hashtable<String, ArrayList<Object>> data = xmlData.getData();
		wmdsData = (Hashtable<String, ArrayList<Object>>) data.get(
			ISystemDataConstants.WMDS_RESULT_ITEMS).get(
			0);
		wmdsItem = (Hashtable<String, ArrayList<Object>>) wmdsData.get(
			ISystemDataConstants.WMDS_WMDSITEM).get(
			0);
		return getTransferValue(
			wmdsItem, ISystemDataConstants.WMDS_WMDSITEM_ITEM_TYPE);
	}
	
	public static void main(String[] args)
	{
		String xmlStr = "<WMDSParam><Items><WMDSItem><Description></Description><ItemType></ItemType><Ref9></Ref9><Value></Value><Ref8></Ref8><Ref7></Ref7><Ref6></Ref6><Ref5>测试用供应商批次ORD201308221</Ref5><Ref4>测试用供应商4020017</Ref4><Ref3>admin</Ref3><Ref2>2013-08-22</Ref2><Key></Key><Ref1>鸡肉(鸡胸肉 X)</Ref1></WMDSItem></Items><Operator></Operator><Operate>CREATELABEL</Operate></WMDSParam>";
		String xmlStr2 = "<WMDSParam><Items><WMDSItem><Description></Description><ItemType></ItemType><Ref9></Ref9><Value></Value><Ref8></Ref8><Ref7></Ref7><Ref6></Ref6><Ref5>测试用供应商批次ORD201308221</Ref5><Ref4>测试用供应商4020017</Ref4><Ref3>admin</Ref3><Ref2>2013-08-22</Ref2><Key></Key><Ref1>鸡肉(鸡胸肉 X)</Ref1></WMDSItem></Items><Operator>NEMO</Operator><Operate>CREATELABEL</Operate></WMDSParam>";
		try
		{
			String result = MDUtils.invokeDNetWebService(
				END_POINT, NAME_SPACE, METHOD_NAME_WMDS, SOAP_ACTION_WMDS, PARAMETER_NAME, xmlStr );
			XmlData xmlData = XMLUtils.strToXMLData(result);
			Hashtable<String, ArrayList<Object>> data = xmlData.getData();
		}
		catch (Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	

	//---------------------------------Source Component-----------------------------------------------
	
	public String generateTestBarcode(String priffex)
	{
		Time time = getFunctions().getDBTime();
		return priffex+DateTimeUtils.formatDate(time, "yyyyMMddHHmmss");
	}

	/**
	 * 根据当前产品和条码类型获得条码规则
	 * @param barcodeType 条码类型
	 */
	private BarCodeRule getBarcode(int barcodeType)
		throws Exception
	{
		BarCodeRule barCodeRule = new BarCodeRule();
		barCodeRule.setBarcodeRule(BARCODE_RULE);
		barCodeRule.setBarcodeType(barcodeType);
		barCodeRule.setTemplate(getTemplate(barcodeType));
		return barCodeRule;
	}
	
	public String getTemplate(int barcodeType)
	{
		return barcodeTemplate.get(Long.valueOf(barcodeType));
	}
	
	/**
	 * 生成条码
	 */
	private synchronized BarCodeRule generateBarcode(int barcodeType) throws Exception
	{
		return getBarcode(barcodeType);
		
		//OLD
//		BarCodeRule barCodeRule = getBarcode(barcodeType);
		
		
//		String barCode = new String(barCodeRule.getBarcodeRule());
//		
//		Calendar calendar = getFunctions().getDBTime().getCalendar();
//		int year = calendar.get(Calendar.YEAR);
//		int month = calendar.get(Calendar.MONTH) + 1;
//		int day = calendar.get(Calendar.DATE);
//		int week = calendar.get(Calendar.WEEK_OF_YEAR);
//		
//		String ycode = format(new Integer(year).toString(), 4, "0");
//		String mcode = format(new Integer(month).toString(), 2, "0");
//		String dcode = format(new Integer(day).toString(), 2, "0");
//		String wcode = format(new Integer(week).toString(), 2, "0");
//		String ymdCode = ycode + mcode + dcode;
//
//		//获得下一个批次号
//		String sn = String.valueOf(getNextSn(barcodeType,ymdCode));
//		
//		sn = format(sn, 4,
//					SN_PREFIX);
//
//		if(ycode!=null)
//		{
//			barCode = barCode.replaceFirst(WILDCARD_YEAR,ycode);
//		}
//		if(mcode!=null)
//		{
//			barCode = barCode.replaceFirst(WILDCARD_MONTH,mcode);
//		}
//		
//		if(dcode!=null)
//		{
//			barCode = barCode.replaceFirst(WILDCARD_DAY,dcode);
//		}
//		
//		if(sn!=null)
//		{
//			barCode = barCode.replaceFirst(WILDCARD_SN,sn);
//		}
//		if(wcode!=null)
//		{
//			barCode = barCode.replaceFirst(WILDCARD_WEEK,wcode);
//		}
//		// 替换条码
//		barCode = barCode.replaceFirst(WILDCARD_YEAR,ycode)
//								 .replaceFirst(WILDCARD_MONTH,mcode)
//								 .replaceFirst(WILDCARD_DAY,dcode)
//								 .replaceFirst(WILDCARD_SN,sn)
//								 .replaceFirst(WILDCARD_WEEK,wcode);
//		
//		//NATIVE
//		barCodeRule.setBarcode(barCode);
//		return barCodeRule;
	}
	
	/**
	 * 生成打印记录
	 */
	public static synchronized Response logPrintRecord(Functions functions,String barcode,int barcodeType,String orderName,String productionLineName,String partDescription){
		ATDefinition atDefinition = functions.getATDefinition(AT_TABLE_IM_PRINT_RECORD);
		Response res = atDefinition.createATRow();
		if(res.isOk()){
			ATRow atRow = (ATRow) res.getResult();
			atRow.setValue(AT_COLUMN_IM_PRINT_RECORD_BARCODE,barcode);
			atRow.setValue(AT_COLUMN_IM_PRINT_RECORD_RECORD_TYPE, IPrintConstants.PRINT_RECORD_TYPE_PRINT);
			atRow.setValue(AT_COLUMN_IM_PRINT_RECORD_BARCODE_TYPE, Long.parseLong(String.valueOf(barcodeType)));
			atRow.setValue(AT_COLUMN_IM_PRINT_RECORD_ORDER_NUMBER, orderName);
			atRow.setValue(AT_COLUMN_IM_PRINT_RECORD_PRODUCTION_LINE_NAME, productionLineName);
			atRow.setValue(AT_COLUMN_IM_PRINT_RECORD_PART_DESCRIPTION, partDescription);
			res = atRow.save(functions.getDBTime(), null, null);
		}
		return res;
	}
	
	/**
	 * 生成补印记录
	 * @throws DatasweepException 
	 */
	public static synchronized Response logRePrintRecord(Functions functions,String barCode) throws DatasweepException{
		ATRowFilter atRowFilter = functions.createATRowFilter(AT_TABLE_IM_PRINT_RECORD);
		atRowFilter.forColumnNameEqualTo(AT_COLUMN_IM_PRINT_RECORD_BARCODE, barCode);
		Vector atRows = functions.getFilteredATRows(atRowFilter, false);
		ATRow atRow = (ATRow) atRows.firstElement();
		String orderNumber = (String) atRow.getValue(AT_COLUMN_IM_PRINT_RECORD_ORDER_NUMBER);
		String productionLineName = (String) atRow.getValue(AT_COLUMN_IM_PRINT_RECORD_PRODUCTION_LINE_NAME);
		String partDescription = (String)atRow.getValue(AT_COLUMN_IM_PRINT_RECORD_PART_DESCRIPTION);
		Long barcodeType = (Long)atRow.getValue(AT_COLUMN_IM_PRINT_RECORD_BARCODE_TYPE);
		
		ATDefinition atDefinition = functions.getATDefinition(AT_TABLE_IM_PRINT_RECORD);
		Response res = atDefinition.createATRow();
		if(res.isOk()){
			ATRow atRowSave = (ATRow) res.getResult();
			atRowSave.setValue(AT_COLUMN_IM_PRINT_RECORD_BARCODE, barCode);
			atRowSave.setValue(AT_COLUMN_IM_PRINT_RECORD_RECORD_TYPE, IPrintConstants.PRINT_RECORD_TYPE_REPRINT);
			atRowSave.setValue(AT_COLUMN_IM_PRINT_RECORD_BARCODE_TYPE, barcodeType);
			atRowSave.setValue(AT_COLUMN_IM_PRINT_RECORD_ORDER_NUMBER, orderNumber);
			atRowSave.setValue(AT_COLUMN_IM_PRINT_RECORD_PRODUCTION_LINE_NAME, productionLineName);
			atRowSave.setValue(AT_COLUMN_IM_PRINT_RECORD_PART_DESCRIPTION, partDescription);
			res = atRowSave.save(functions.getDBTime(), null, null);
		}
		return res;
	}

	/**
	 * 打印/补打条码
	 */
	public void printBarCode(String barcode,int printType) throws Exception
	{
		try
		{
			String templatePath = getTemplate(printType);
			if (generateDataFile(
				templatePath, barcode,printType))
			{
				executeLabelMatrix(
					templatePath, labelMatrixPath);
			}
		}
		catch (Exception e)
		{
			throw new MESException(e, MODULE_IM, "打印/补打条码");
		}
	}
	
	/**
	 * 执行打印程序
	 */
	private void executeLabelMatrix(String dataFile, String labelMatrixPath) throws Exception {
		//获得Label Matrix的程序地址
		if (StringUtils.isNull(labelMatrixPath)) {
			throw new Exception("Label Matrix程序地址不允许为空");
		}
		
		File file = new File(dataFile);
		if(file != null && file.exists())
		{
			//调用命令
			String cmd = labelMatrixPath + "  " + dataFile;
			getFunctions().exec(cmd);
		}
		else
		{
			throw new Exception("Label Matrix条码模板文件不存在");
		}
		
	}

	/**
	 * 生成数据文件
	 * @param dataFile 文件路径
	 * @param barcode 条码
	 */
	private synchronized boolean generateDataFile(String dataFile, String barcode,int printType)
		throws Exception
	{
		dataFile = dataFile.trim().substring(
			0, dataFile.lastIndexOf(".")) + ".txt";

		FileOutputStream fileoutputstream = null;
		BufferedWriter bufferedwriter = null;
		try
		{
			File file = new File(dataFile);
			if (!file.exists())
			{
				file.createNewFile();
			}
			fileoutputstream = new FileOutputStream(dataFile);
			bufferedwriter = new BufferedWriter(new OutputStreamWriter(fileoutputstream));
			String barcodeMarker = null;
			String barcodeContent = "\""+barcode.replaceAll(",", "\",\"")+"\"";
			if(BARCODE_TYPE_MATERIAL == printType)
			{
				barcodeMarker = MATERIAL_BARCODE_MARKER;
			}
			else if(BARCODE_TYPE_LOT == printType)
			{
				barcodeMarker = LOT_BARCODE_MARKER;
			}
			
			bufferedwriter.write(barcodeMarker);
			bufferedwriter.newLine();
			bufferedwriter.write(barcodeContent);
			bufferedwriter.flush();
			return true;
		}
		catch (FileNotFoundException e)
		{
			throw new Exception("找不到指定文件" + dataFile);
		}
		catch (IOException e)
		{
			throw new Exception("文件读取有误");
		}
		finally
		{
			try
			{
				bufferedwriter.close();
			}
			catch (IOException ex)
			{
				EventLog.logException(
					ex, null, null);
			}
		}
	}
	
//	/**
//	 * 获得条码长度
//	 */
//	private int getSnLen(String barcodeRule) {
//		int loc = barcodeRule.indexOf("[#");
//		int loc1 = barcodeRule.indexOf("#]");
//		String sn = barcodeRule.substring(
//			loc + 1,
//			loc1 + 1);
//		return sn.length();
//	}

	
	
	/**
	 * 获得下一次批次号
	 */
	private synchronized int getNextSn(int barcodeType,String ymdCode) throws Exception
	{
		String sequenceName = "SEQNAME"+barcodeType+ymdCode;
		return getSequenceNumber(sequenceName);
	}
	
//	public static void main(String[] args)
//	{
//		String lotName = "123456789";
//		System.out.println(lotName.substring(lotName.length()-2, lotName.length()));
//	}
	//---------------------------------Source Component End-----------------------------------------------

}
